package com.psychologyCommunity.Community.config;

import com.psychologyCommunity.Community.util.CommunityConstance;
import com.psychologyCommunity.Community.util.CommunityUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter implements CommunityConstance {
    @Override
    public void configure(WebSecurity web) throws Exception{
        //忽略掉对静态资源的拦截，resources下的静态资源直接访问 不用拦截
        web.ignoring().antMatchers("/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //授权
        //是hasAnyAuthority(身份) 就可以访问哪些页面.antMatchers(页面路径)
        //anyRequest().permitAll() 除了上面限制的 .antMatchers(页面路径)中的路径，其他的路径不管登没登陆都可以访问
        //1.只要是登录的用户 不管是什么身份 都可以访问的
        http.authorizeRequests()
                .antMatchers(
                    "/user/setting",
                        "/user/upload",
                        "user/profile",
                                "/letter/**",
                                "/notice/**",
                                "/discuss/add",
                                "/comment/add/**",
                                "/like",
                                "/follow",
                                "/unfollow"
                )
                .hasAnyAuthority(
                    AUTHORITY_ADMIN,
                        AUTHORITY_USER,
                        AUTHORITY_MODERATOR
                )
                .antMatchers(
                        "/discuss/top",
                        "/discuss/wonderful"
                )
                .hasAnyAuthority(
                        AUTHORITY_ADMIN,
                        AUTHORITY_USER,
                        AUTHORITY_MODERATOR
                )
                .antMatchers(
                        "/discuss/delete"

                )
                .hasAnyAuthority(
                        AUTHORITY_ADMIN
                ).anyRequest().permitAll()
                .and().csrf().disable();
        //普通请求希望你 返回的是html，异步请求一般希望你返回Json

        //权限不足时的处理
        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
            //没有登录时的处理
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                String header = request.getHeader("x-requested with");//在header中通过key为x-requested with 拿到一个header
                if ("XMLHttpRequest".equals(header)) { //如果返回的头部是XMLHttpRequest代表的就是一个异步请求，此时给浏览器返回一个JSON字符串
                   //手动返回一个JSON字符串
                    response.setContentType("application/plain;charset=utf-8");
                    PrintWriter writer = response.getWriter();
                    writer.write(CommunityUtil.getJSONString(403,"宝，你还没有登录啊~"));
                } else {//普通请求就直接跳转到登录页面
                    response.sendRedirect(request.getContextPath()+"/login");
                }
            }
        })
                .accessDeniedHandler(new AccessDeniedHandler() {
                    //权限不足的处理
                    @Override
                    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                        String header = request.getHeader("x-requested with");//在header中通过key为x-requested with 拿到一个header
                        if ("XMLHttpRequest".equals(header)) { //如果返回的头部是XMLHttpRequest代表的就是一个异步请求，此时给浏览器返回一个JSON字符串
                            //手动返回一个JSON字符串
                            response.setContentType("application/plain;charset=utf-8");
                            PrintWriter writer = response.getWriter();
                            writer.write(CommunityUtil.getJSONString(403,"宝，你没有访问此功能的权限，如果需要可以联系管理员申请哦~"));
                        } else {//普通请求就直接跳转到登录页面
                            response.sendRedirect(request.getContextPath()+"/denied");
                        }
                    }
                });
        //Filter的处理在dispatchServlet之前，即也在controller之前
        // Security底层默认会拦截/logout 请求，进行退出处理--覆盖他默认的逻辑，才能执行我们自己的退出代码
        http.logout().logoutUrl("/securitylogout");

    }
}
